package com.rapida.db;

import android.content.Context;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.AndroidRuntimeException;

import com.rapida.framwork.RapidaLog;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by mm on 15-1-19.
 */
public class SQLiteFactory extends SQLitePersistentObject {
	private static SQLiteFactory inst;
	private SQLitePersistentObject mSQL;

	public SQLiteFactory(Context context) {
		super(context);
	}

	public static void init(Context context) {
		if (inst == null) {
			inst = new SQLiteFactory(context);
		}
	}

	public static void delAll(Class<?> cls) {
		if (inst == null) {
			AndroidRuntimeException exception = new AndroidRuntimeException("inst can not be null");
			RapidaLog.e(exception, "invoke init()");
			throw exception;
		}
		SQLiteDatabase db = mHelper.getWritableDatabase();
		try {
			db.execSQL("DELETE FROM " + cls.getSimpleName());
		} catch (Exception e) {
			RapidaLog.e("delAll exception");
		} finally {
			db.close();
		}
	}

	public static void delAll(Class<?> cls, String sql, String[] selectionArgs) {
		if (inst == null) {
			AndroidRuntimeException exception = new AndroidRuntimeException("inst can not be null");
			RapidaLog.e(exception, "invoke init()");
			throw exception;
		}
		SQLiteDatabase db = mHelper.getWritableDatabase();
		try {
			db.execSQL("DELETE FROM " + cls.getSimpleName() + " WHERE " + sql, selectionArgs);
		} catch (Exception e) {
			RapidaLog.e("delAll exception");
		} finally {
			db.close();
		}
	}

	public static List findAll(Class<?> cls, String sql, String[] selectionArgs) {
		if (inst == null) {
			AndroidRuntimeException exception = new AndroidRuntimeException("inst can not be null");
			RapidaLog.e(exception, "invoke init()");
			throw exception;
		}
		SQLiteDatabase db = mHelper.getReadableDatabase();
		List list = new ArrayList();
		try {
			Cursor c = db.rawQuery("SELECT * FROM " + cls.getSimpleName() + " WHERE " + sql, selectionArgs);
			while (c.moveToNext()) {
				Constructor constructor = cls.getDeclaredConstructor(new Class[]{Context.class});
				Object classObj = constructor.newInstance(mContext);
				Field[] fields = classObj.getClass().getDeclaredFields();
				if (fields != null && fields.length > 0) {
					for (Field field : fields) {
						field.setAccessible(true);
						IDBOutlet outlet = field.getAnnotation(IDBOutlet.class);
						if (outlet != null) {
							String key = outlet.id();
							String value = c.getString(c.getColumnIndex(key));
							field.set(classObj, value);
						}
					}
				}
				list.add(classObj);
			}
		} catch (Exception e) {
			RapidaLog.e("findAll exception");
		} finally {
			db.close();
		}
		return list;
	}

	public static List findAll(Class<?> cls) {
		if (inst == null) {
			AndroidRuntimeException exception = new AndroidRuntimeException("inst can not be null");
			RapidaLog.e(exception, "invoke init()");
			throw exception;
		}
		SQLiteDatabase db = mHelper.getReadableDatabase();
		List list = new ArrayList();
		try {
			Cursor c = db.rawQuery("SELECT * FROM " + cls.getSimpleName(), null);
			while (c.moveToNext()) {
				Constructor constructor = cls.getDeclaredConstructor(new Class[]{Context.class});
				Object classObj = constructor.newInstance(mContext);
				Field[] fields = classObj.getClass().getDeclaredFields();
				if (fields != null && fields.length > 0) {
					for (Field field : fields) {
						field.setAccessible(true);
						IDBOutlet outlet = field.getAnnotation(IDBOutlet.class);
						if (outlet != null) {
							String key = outlet.id();
							String value = c.getString(c.getColumnIndex(key));
							field.set(classObj, value);
						}
					}
				}
				list.add(classObj);
			}
		} catch (Exception e) {
			RapidaLog.e("findAll init()");
		} finally {
			db.close();
		}
		return list;
	}
}
